<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>xiaxuchen的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="xiaxuchen的博客">
<meta property="og:url" content="http://yoursite.com/page/3/index.html">
<meta property="og:site_name" content="xiaxuchen的博客">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="xiaxuchen">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="./atom.xml" title="xiaxuchen的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="./css/style.css">

<meta name="generator" content="Hexo 5.0.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="./" id="logo">xiaxuchen的博客</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="./">Home</a>
        
          <a class="main-nav-link" href="./archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="./atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-后端/阿里云服务器开启redis端口" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%80%E5%90%AFredis%E7%AB%AF%E5%8F%A3/" class="article-date">
  <time datetime="2020-08-07T15:08:02.120Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="阿里云服务器开启redis端口"><a href="#阿里云服务器开启redis端口" class="headerlink" title="阿里云服务器开启redis端口"></a>阿里云服务器开启redis端口</h2><ol>
<li>查看当前防火墙状态</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl status firewalld</span><br></pre></td></tr></table></figure>

<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200203122722746.png" alt="image-20200203122722746"></p>
<p>当前表示没有启动firewall</p>
<ol start="2">
<li>启动防火墙</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">systemctl start firewalld &#x2F;&#x2F;运行后不会有输出</span><br><span class="line">systemctl status firewalld &#x2F;&#x2F; 查看一下当前状态</span><br></pre></td></tr></table></figure>

<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200203122834270.png" alt="image-20200203122834270"></p>
<ol start="3">
<li>开启端口</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --permanent --zone&#x3D;public --add-port&#x3D;6379&#x2F;tcp &#x2F;&#x2F;如果是其他端口可以把6379换掉</span><br><span class="line">firewall-cmd --permanent --query-port&#x3D;6379&#x2F;tcp &#x2F;&#x2F; 查询当前端口的状态</span><br></pre></td></tr></table></figure>

<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200203123223088.png" alt="image-20200203123223088"></p>
<ol start="4">
<li>重启防火墙</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --reload &#x2F;&#x2F;重启，成功打印success</span><br></pre></td></tr></table></figure>

<ol start="5">
<li><p>配置安全组规则</p>
<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200203123708015.png" alt="image-20200203123708015"></p>
</li>
</ol>
<p>配置ssr(<a target="_blank" rel="noopener" href="http://blog.chinaunix.net/uid-25530360-id-5595974.html">http://blog.chinaunix.net/uid-25530360-id-5595974.html</a>)</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%80%E5%90%AFredis%E7%AB%AF%E5%8F%A3/" data-id="ckdkdagvf000pvoutg3lg42ns" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/WxInterceptor的实现" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/WxInterceptor%E7%9A%84%E5%AE%9E%E7%8E%B0/" class="article-date">
  <time datetime="2020-08-07T15:08:02.116Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="WxInterceptor的实现"><a href="#WxInterceptor的实现" class="headerlink" title="WxInterceptor的实现"></a>WxInterceptor的实现</h2><h3 id="1-简介"><a href="#1-简介" class="headerlink" title="1. 简介"></a>1. 简介</h3><p>由于微信公众号与用户交互时只会向服务器配置的URL发送post请求，故不能定义多个接口处理不同的请求，用户与微信公众号交互会访问CoreController的如下代码:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, HttpSession session)</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">      request.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">      response.setCharacterEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">      PrintWriter out = response.getWriter();</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">          <span class="comment">// 微信服务器推送过来的是XML格式。</span></span><br><span class="line">          WxXmlMessage wxXmlMessage = XStreamTransformer.fromXml(WxXmlMessage.class, request.getInputStream());</span><br><span class="line">          <span class="comment">// 这里遍历Interceptor集合，根据他们的intercept方法返回的值，判断他们是否拦截请求，若拦截，则调用他们的handle方法处理请求</span></span><br><span class="line">          <span class="keyword">for</span> (WXInterceptor interceptor : interceptors) &#123;</span><br><span class="line">              <span class="keyword">if</span>(interceptor.intercept(request,response))</span><br><span class="line">              &#123;</span><br><span class="line">                  interceptor.handle(request,response);</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">          e.printStackTrace();</span><br><span class="line">      &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">          out.close();</span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>



<h3 id="2-用法"><a href="#2-用法" class="headerlink" title="2. 用法"></a>2. 用法</h3><p>用户需自定义拦截器实现WxInterceptor，在intercept方法中根据请求的信息返回是否拦截请求，若拦截，则会调用handle方法处理，可以在handle方法完成具体的逻辑处理，最后需给自定义类添加@Interceptor注解将其加入Bean容器</p>
<h3 id="3-原理"><a href="#3-原理" class="headerlink" title="3. 原理"></a>3. 原理</h3><p>Interceptor注解</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">@Target(&#123;ElementType.TYPE&#125;)</span><br><span class="line">@Retention(RetentionPolicy.RUNTIME)</span><br><span class="line">@Documented</span><br><span class="line">@Component</span><br><span class="line">public @interface Interceptor &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>由于其被@Component注解，故被其注解的注解类也就拥有了@Component的作用，为什么不用@Component的原因是自定义的注解更具有语义化</p>
<p>InterceptorPostProcessor</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WxInterceporPostProcessor</span> <span class="keyword">implements</span> <span class="title">BeanPostProcessor</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">postProcessAfterInitialization</span><span class="params">(Object bean, String beanName)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (bean.getClass() == WXInterceptor.class)</span><br><span class="line">        &#123;</span><br><span class="line">            CoreController.addInterceptor((WXInterceptor) bean);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>在Spring初始化容器之后，WxInterceptorPostProcessor会逐个判断每个Bean是否是WxInterceptor类型，如果是的话，就加入CoreController的拦截器列表，这样CoreController就获取到了我们编写的自定义Interceptor，当用户交互请求到来时又会遍历拦截器列表进行处理</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/WxInterceptor%E7%9A%84%E5%AE%9E%E7%8E%B0/" data-id="ckdkdagv4000mvoutcvfw69sa" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/Vue-Router" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/Vue-Router/" class="article-date">
  <time datetime="2020-08-07T15:08:02.112Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="Vue-Router"><a href="#Vue-Router" class="headerlink" title="Vue-Router"></a>Vue-Router</h2><h3 id="一、目录结构"><a href="#一、目录结构" class="headerlink" title="一、目录结构"></a>一、目录结构</h3><p>安装</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i vue-router -S</span><br></pre></td></tr></table></figure>



<p>在src下的router文件夹中放置index.js集成vue-router的分离的配置项,比如我们会把routes分离在统计目录的routes.js文件中</p>
<p>routes.js</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">import HelloWorld from &#39;@&#x2F;components&#x2F;HelloWorld&#39;</span><br><span class="line"></span><br><span class="line">export default [</span><br><span class="line">  &#123;</span><br><span class="line">    path: &#39;&#x2F;hello&#39;,</span><br><span class="line">    name: &#39;HelloWorld&#39;,</span><br><span class="line">    component: HelloWorld</span><br><span class="line">  &#125;</span><br><span class="line">]</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>index.js</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">import Vue from &#39;vue&#39;</span><br><span class="line">import Router from &#39;vue-router&#39;</span><br><span class="line">import routes from &#39;@&#x2F;router&#x2F;routes&#39; &#x2F;&#x2F; 引入routes文件中的配置</span><br><span class="line"></span><br><span class="line">Vue.use(Router)</span><br><span class="line"></span><br><span class="line">export default new Router(&#123;</span><br><span class="line">  mode: &#39;history&#39;, &#x2F;&#x2F; 使用history模式</span><br><span class="line">  routes</span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>这个鬼视频总是在后面才出现关键配置:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hisApiFallBack: &#123;</span><br><span class="line">    index: &#39;index.html&#39;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="二、-配置项解析"><a href="#二、-配置项解析" class="headerlink" title="二、 配置项解析"></a>二、 配置项解析</h3><ol>
<li><p>mode</p>
<p>​    一般使用history，就是正常的路由，不会有#</p>
</li>
<li><p>routes</p>
<ol>
<li><p>path</p>
<p>组件的访问路径</p>
</li>
<li><p>component</p>
<p>渲染的组件</p>
</li>
<li><p>redirect</p>
<p>重定向到相应的页面</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F; 如下配置将&#x2F;重定向到&#x2F;login页面</span><br><span class="line">&#123;</span><br><span class="line">    path: &#39;&#x2F;&#39;,</span><br><span class="line">    redirect: &#39;&#x2F;login&#39;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>meta </p>
<p>配置额外的信息</p>
</li>
<li><p>children</p>
<p>当组件中router-view的时候需要它配置组件</p>
</li>
</ol>
</li>
<li><p>base</p>
<p>用于管理应用路径，可能应用的路径是/app/，所以我们就要配置base</p>
</li>
</ol>
<h3 id="三、"><a href="#三、" class="headerlink" title="三、"></a>三、</h3><ul>
<li><p>transition</p>
<p>可以给router-view加一些淡入淡出效果</p>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/Vue-Router/" data-id="ckdkdagv3000lvoutbhsk96ha" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/vue + springmvc前后端传递数组参数问题" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/vue%20+%20springmvc%E5%89%8D%E5%90%8E%E7%AB%AF%E4%BC%A0%E9%80%92%E6%95%B0%E7%BB%84%E5%8F%82%E6%95%B0%E9%97%AE%E9%A2%98/" class="article-date">
  <time datetime="2020-08-07T15:08:02.073Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="vue-springmvc前后端传递数组参数问题"><a href="#vue-springmvc前后端传递数组参数问题" class="headerlink" title="vue + springmvc前后端传递数组参数问题"></a>vue + springmvc前后端传递数组参数问题</h1><h2 id="spring-mvc获取数组参数的两种方式"><a href="#spring-mvc获取数组参数的两种方式" class="headerlink" title="spring mvc获取数组参数的两种方式"></a>spring mvc获取数组参数的两种方式</h2><p>实现要求：请求需要获取一个ids的Integer类型的数组</p>
<ol>
<li><p>方式一</p>
<p>请求中的请求参数以如下方式传递：</p>
<p>​    <strong>http://主机名:端口名/路径?ids=1&amp;ids=2</strong></p>
<p>springmvc服务器端不需要再参数前添加注解，直接使用<strong>Integer[]**或</strong>List&lt;Integer&gt;**类型即可，代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/getIds&quot;)</span></span><br><span class="line"><span class="comment">// 下面的@RequestParam(&quot;ids&quot;)可以不要</span></span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">getIds</span><span class="params">(<span class="meta">@RequestParam(&quot;ids&quot;)</span> Integer[] ids)</span></span>&#123;&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>方式二</p>
<p>请求中的请求参数以如下方式传递(其中的**[]**需要进行URL编码)：</p>
<p>​    <strong>http://主机名:端口名/路径?ids[]=1&amp;ids[]=2</strong></p>
<p>在方式一中的参数前需要添加@RequestParam注解，并注明参数名称为**ids[]**，代码如下:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/getIds&quot;)</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">getIds</span><span class="params">(<span class="meta">@RequestParam(&quot;ids[]&quot;)</span> String[] ids)</span></span>&#123;&#125;</span><br></pre></td></tr></table></figure>

</li>
</ol>
<h2 id="遇到的问题"><a href="#遇到的问题" class="headerlink" title="遇到的问题:"></a>遇到的问题:</h2><h3 id="服务器无法识别字符"><a href="#服务器无法识别字符" class="headerlink" title="服务器无法识别字符"></a>服务器无法识别字符</h3><ul>
<li><p>问题描述</p>
<blockquote>
<p>Invalid character found in the request target. The valid characters are …</p>
</blockquote>
<p>这个问题是我在使用axios发送delete请求时传输数组数据遇到的，原因是axios没有将数组的中括号**[]**编码，服务器端无法识别导致的</p>
</li>
<li><p>解决办法</p>
<p>使用qs，对参数进行转码</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">const del &#x3D; function (apiPath, params, successCallback, errorCallback) &#123;</span><br><span class="line">  return http.delete(apiPath, &#123;</span><br><span class="line">    params: params,</span><br><span class="line">    &#x2F;&#x2F; 这个将对参数进行转码</span><br><span class="line">    paramsSerializer: params &#x3D;&gt; &#123;</span><br><span class="line">      return qs.stringify(params, &#123; indices: false &#125;)</span><br><span class="line">    &#125; &#125;)</span><br><span class="line">  &#x2F;&#x2F; thenResponse(req, successCallback, errorCallback)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



</li>
</ul>
<p>  以上代码封装了向服务器发送delete请求的操作</p>
<h3 id="axios只发送options请求"><a href="#axios只发送options请求" class="headerlink" title="axios只发送options请求"></a>axios只发送options请求</h3><ul>
<li><p>问题描述</p>
<p>由于跨域的预检机制，每次发送非简单请求的时候axios都会发送一次options请求查看是否有权限访问，但是我发送请求时发送完options请求后就不再发真正的请求了.</p>
</li>
<li><p>问题原因</p>
<p>我在使用axios.create方法时指定了<strong>withCredentials: true</strong></p>
<p>错误代码如下:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> http = axios.create(&#123;</span><br><span class="line">  baseURL: <span class="string">&#x27;http://localhost:8086/app&#x27;</span>,</span><br><span class="line">  <span class="comment">// 这里的代码导致了错误，删除即可</span></span><br><span class="line">  withCredentials: <span class="literal">true</span>,</span><br><span class="line">  transformRequest: [<span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> newData = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> k <span class="keyword">in</span> data) &#123;</span><br><span class="line">      <span class="keyword">if</span> (data.hasOwnProperty(k) === <span class="literal">true</span>) &#123;</span><br><span class="line">        newData += <span class="built_in">encodeURIComponent</span>(k) + <span class="string">&#x27;=&#x27;</span> + <span class="built_in">encodeURIComponent</span>(data[k]) + <span class="string">&#x27;&amp;&#x27;</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> newData</span><br><span class="line">  &#125;]</span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>





</li>
</ul>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul>
<li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS">跨域中的预检机制MDN文档</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/vue%20+%20springmvc%E5%89%8D%E5%90%8E%E7%AB%AF%E4%BC%A0%E9%80%92%E6%95%B0%E7%BB%84%E5%8F%82%E6%95%B0%E9%97%AE%E9%A2%98/" data-id="ckdkdagvc000ovoutd34b0ips" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/SSM各配置的解析" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/SSM%E5%90%84%E9%85%8D%E7%BD%AE%E7%9A%84%E8%A7%A3%E6%9E%90/" class="article-date">
  <time datetime="2020-08-07T15:08:02.069Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="SSM各配置的解析"><a href="#SSM各配置的解析" class="headerlink" title="SSM各配置的解析"></a>SSM各配置的解析</h2><h3 id="一、Spring配置解析"><a href="#一、Spring配置解析" class="headerlink" title="一、Spring配置解析"></a>一、Spring配置解析</h3><h4 id="1-context-annotation-config"><a href="#1-context-annotation-config" class="headerlink" title="1. context:annotation-config"></a>1. context:annotation-config</h4><p>​    用于激活@AutoWired、@Resource、@PreDestory等注解的处理，使得使用这些注解生效，原理是配置了相应的BeanPostProcessor </p>
<h4 id="2-context-component-scan"><a href="#2-context-component-scan" class="headerlink" title="2.context:component-scan"></a>2.context:component-scan</h4><p>​    扫描相应包下的@Component、@Repository、@Service、@Controller等注解，并将被注解的类加入Spring容器，不用一个一个Bean配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 将会扫描com.online.college包以及其子包下的所有java文件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.online.college&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>



<h4 id="3-PlaceholderConfigurer"><a href="#3-PlaceholderConfigurer" class="headerlink" title="3. PlaceholderConfigurer"></a>3. PlaceholderConfigurer</h4><p>​    可以用于加载多个配置文件，spring使用context:property-placeholder作为替代的简便方案</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 加载jdbc 和 app配置文件 --&gt;</span><br><span class="line">&lt;bean class&#x3D;&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot; lazy-init&#x3D;&quot;true&quot;&gt;</span><br><span class="line">   &lt;property name&#x3D;&quot;systemPropertiesModeName&quot; value&#x3D;&quot;SYSTEM_PROPERTIES_MODE_OVERRIDE&quot; &#x2F;&gt;</span><br><span class="line">   &lt;property name&#x3D;&quot;ignoreResourceNotFound&quot; value&#x3D;&quot;true&quot; &#x2F;&gt;</span><br><span class="line">   &lt;property name&#x3D;&quot;locations&quot;&gt;</span><br><span class="line">      &lt;list&gt;</span><br><span class="line">         &lt;value&gt;classpath:&#x2F;jdbc.properties&lt;&#x2F;value&gt;</span><br><span class="line">         &lt;value&gt;classpath:&#x2F;application.properties&lt;&#x2F;value&gt; </span><br><span class="line">      &lt;&#x2F;list&gt;</span><br><span class="line">   &lt;&#x2F;property&gt;</span><br><span class="line">&lt;&#x2F;bean&gt;</span><br></pre></td></tr></table></figure>

<h3 id="二、MyBatis配置解析"><a href="#二、MyBatis配置解析" class="headerlink" title="二、MyBatis配置解析"></a>二、MyBatis配置解析</h3><h4 id="1-DataSource"><a href="#1-DataSource" class="headerlink" title="1. DataSource"></a>1. DataSource</h4><p>​    数据源接口，用于获取数据库连接的统一接口。DriverManager也是获取数据库连接的统一接口，他们之间的区别是，前者面相的是具体的数据库，去真正的连接数据库，获取到连接之后可能会通过数据库连接池等对连接进行优化处理，而后者正是在此情况下进行的统一封装，具体如何优化交由个数据库连接池厂商，而用户只需提供数据库连接信息，我们便能从DataSource接口中获取优化后的连接</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.mchange.v2.c3p0.ComboPooledDataSource&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driverClass&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;datasource.driverClassName&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;jdbcUrl&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;datasource.url&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;user&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;datasource.username&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;datasource.password&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;acquireIncrement&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.acquireIncrement&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;initialPoolSize&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.initialPoolSize&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;minPoolSize&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.minPoolSize&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;maxPoolSize&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.maxPoolSize&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;maxIdleTime&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.maxIdleTime&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;maxStatements&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.maxStatements&#125;&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;autoCommitOnClose&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;c3p0.autoCommitOnClose&#125;&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="3-SqlSessionFactory"><a href="#3-SqlSessionFactory" class="headerlink" title="3. SqlSessionFactory"></a>3. SqlSessionFactory</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;sqlSessionFactory&quot;</span> <span class="attr">class</span>=<span class="string">&quot;org.mybatis.spring.SqlSessionFactoryBean&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--mybatis配置文件的位置--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;configLocation&quot;</span> <span class="attr">value</span>=<span class="string">&quot;classpath:mybatis-config.xml&quot;</span> /&gt;</span>  </span><br><span class="line">    <span class="comment">&lt;!--数据源--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span> /&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--mapper文件放置的位置--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;mapperLocations&quot;</span> <span class="attr">value</span>=<span class="string">&quot;classpath*:mapper/*Mapper.xml&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>



<h4 id="4-MapperScannerConfigurer"><a href="#4-MapperScannerConfigurer" class="headerlink" title="4. MapperScannerConfigurer"></a>4. MapperScannerConfigurer</h4><p>​    代理Mapper接口生成实现并加入Spring容器中</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.mybatis.spring.mapper.MapperScannerConfigurer&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--扫描mapper并代理Mapper的实现--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;basePackage&quot;</span> <span class="attr">value</span>=<span class="string">&quot;com.**.dao&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">        </span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h4 id="5-TransationManager"><a href="#5-TransationManager" class="headerlink" title="5. TransationManager"></a>5. TransationManager</h4><p>​    事务管理器标准接口，由个ORM进行实现，当然Spring也有默认实现</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 配置事务管理器 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;transactionManager&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">class</span>=<span class="string">&quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h4 id="6-事务切面"><a href="#6-事务切面" class="headerlink" title="6. 事务切面"></a>6. 事务切面</h4><p>​    配置事务回滚</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">tx:advice</span> <span class="attr">id</span>=<span class="string">&quot;txAdvice&quot;</span> <span class="attr">transaction-manager</span>=<span class="string">&quot;transactionManager&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">tx:attributes</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;do*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;delete*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;merge*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;add*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;save*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;create*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;insert*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;update*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;enable*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;disable*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;generate*&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span> /&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;*&quot;</span> <span class="attr">read-only</span>=<span class="string">&quot;true&quot;</span>/&gt;</span> </span><br><span class="line">            <span class="tag">&lt;/<span class="name">tx:attributes</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">tx:advice</span>&gt;</span></span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">        <span class="tag">&lt;<span class="name">aop:config</span> &gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">aop:pointcut</span> <span class="attr">expression</span>=<span class="string">&quot;execution (* com.online.college.*.service.*.*(..))&quot;</span>  <span class="attr">id</span>=<span class="string">&quot;services&quot;</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">aop:advisor</span> <span class="attr">advice-ref</span>=<span class="string">&quot;txAdvice&quot;</span> <span class="attr">pointcut-ref</span>=<span class="string">&quot;services&quot;</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">aop:config</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!-- 声明式事务 --&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">tx:annotation-driven</span> <span class="attr">transaction-manager</span>=<span class="string">&quot;transactionManager&quot;</span>/&gt;</span></span><br></pre></td></tr></table></figure>





<h3 id="三、SpringMvc配置解析"><a href="#三、SpringMvc配置解析" class="headerlink" title="三、SpringMvc配置解析"></a>三、SpringMvc配置解析</h3><h4 id="1-multipartResolver"><a href="#1-multipartResolver" class="headerlink" title="1. multipartResolver"></a>1. multipartResolver</h4><p>​    对文件上传的支持，配置之后才可以对文件进行解析</p>
<h4 id="2-mvc-annotation-driven"><a href="#2-mvc-annotation-driven" class="headerlink" title="2. mvc:annotation-driven"></a>2. mvc:annotation-driven</h4><p>​    Spring  3.0.x中使用了mvc:annotation-driven后，默认会帮我们注册默认处理请求，参数和返回值的类，其中最主要的两个类：DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter  ，分别为HandlerMapping的实现类和HandlerAdapter的实现类，从3.1.x版本开始对应实现类改为了RequestMappingHandlerMapping和RequestMappingHandlerAdapter。</p>
<ul>
<li><p>HandlerMapping的实现类的作用</p>
<p>实现类RequestMappingHandlerMapping，它会处理@RequestMapping 注解，并将其注册到请求映射表中。</p>
</li>
</ul>
<ul>
<li><p>HandlerAdapter的实现类的作用</p>
<p>实现类RequestMappingHandlerAdapter，则是处理请求的适配器，确定调用哪个类的哪个方法，并且构造方法参数，返回值。</p>
</li>
</ul>
<p>当配置了mvc:annotation-driven后，Spring就知道了我们启用注解驱动。然后Spring通过context:component-scan/标签的配置，会自动为我们将扫描到的@Component，@Controller，@Service，@Repository等注解标记的组件注册到工厂中，来处理我们的请求。</p>
<h4 id="3-mvc-default-servlet-handler"><a href="#3-mvc-default-servlet-handler" class="headerlink" title="3. mvc:default-servlet-handler"></a>3. mvc:default-servlet-handler</h4><p>​    配置了默认servlet后，web.xml默认servlet对应的url-pattern的静态资源可以访问</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>default<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>*.css<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>*.js<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br></pre></td></tr></table></figure>



<h4 id="4-mvc-resources"><a href="#4-mvc-resources" class="headerlink" title="4. mvc:resources"></a>4. mvc:resources</h4><p>​    由于在web.xml配置路径/为dispatchServlet的映射路径，所有的请求都经过dispatcherServlet处理，无法访问到静态资源，故需配置此标签来处理</p>
<p>​    配置文件的访问路径，让外部可以访问到项目中相应位置的文件，location属性为位置，mapping是映射路径可以有通配符</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F; 映射单个文件要写他所在的文件夹路径，文件名在mapping中指定</span><br><span class="line">&lt;mvc:resources mapping&#x3D;&quot;&#x2F;web.xml&quot; location&#x3D;&quot;&#x2F;WEB-INF&#x2F;&quot;&#x2F;&gt;</span><br><span class="line">&#x2F;&#x2F; 映射文件夹使用通配符</span><br><span class="line">&lt;mvc:resources mapping&#x3D;&quot;&#x2F;web&#x2F;**&quot; location&#x3D;&quot;&#x2F;WEB-INF&#x2F;&quot;&#x2F;&gt;</span><br></pre></td></tr></table></figure>

<h4 id="5-viewResolver"><a href="#5-viewResolver" class="headerlink" title="5. viewResolver"></a>5. viewResolver</h4><p>​    用于将逻辑视图转换为物理视图，示例如下</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;viewResolver&quot;</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;</span>&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;prefix&quot;</span> <span class="attr">value</span>=<span class="string">&quot;/WEB-INF/pages/&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;suffix&quot;</span> <span class="attr">value</span>=<span class="string">&quot;.html&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cache&quot;</span> <span class="attr">value</span>=<span class="string">&quot;true&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;contentType&quot;</span> <span class="attr">value</span>=<span class="string">&quot;text/html; charset=UTF-8&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;requestContextAttribute&quot;</span> <span class="attr">value</span>=<span class="string">&quot;request&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>


      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/SSM%E5%90%84%E9%85%8D%E7%BD%AE%E7%9A%84%E8%A7%A3%E6%9E%90/" data-id="ckdkdaguy000ivout8t1z7ufd" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/Spring事务" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/Spring%E4%BA%8B%E5%8A%A1/" class="article-date">
  <time datetime="2020-08-07T15:08:02.065Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="Spring事务"><a href="#Spring事务" class="headerlink" title="Spring事务"></a>Spring事务</h2><h3 id="一、事务的概念"><a href="#一、事务的概念" class="headerlink" title="一、事务的概念"></a>一、事务的概念</h3><h4 id="1-概念"><a href="#1-概念" class="headerlink" title="1. 概念"></a>1. 概念</h4><p>正确的执行一系列动作，从一个状态转换为另一个状态，所有的动作要么全部成功要么全部失败</p>
<h4 id="2-原则"><a href="#2-原则" class="headerlink" title="2. 原则"></a>2. 原则</h4><p>​    ACID</p>
<ol>
<li><p>原子性 </p>
<p>不可分割，要么全部执行，要么全不执行</p>
<ol start="2">
<li>一致性</li>
</ol>
<p>数据库从一种状态转换为另一种状态</p>
<ol start="3">
<li>隔离性</li>
</ol>
<p>在事务正确执行之前，他可能的结果不应显示给其他事务</p>
<ol start="4">
<li>持久性</li>
</ol>
<p>事务正确提交后，永久保存在数据库中</p>
</li>
</ol>
<h3 id="二、java事务"><a href="#二、java事务" class="headerlink" title="二、java事务"></a>二、java事务</h3><h4 id="1-概念-1"><a href="#1-概念-1" class="headerlink" title="1. 概念"></a>1. 概念</h4><p>​    通过java代码操作数据库是保证事务的正确执行</p>
<h4 id="2-实现"><a href="#2-实现" class="headerlink" title="2. 实现"></a>2. 实现</h4><pre><code>1. JDBC事务:用connection手动或自动模式,局限在一个数据库连接中，使用简单
 2. JTA(Java Transaction API):与实现无关，与协议无关，可跨多个数据库或多个DAO,使用比较复杂
 3. 容器事务: 应用服务器提供的，其大多基于JTA，局限于EJB</code></pre>
<h3 id="三、Spring事务管理"><a href="#三、Spring事务管理" class="headerlink" title="三、Spring事务管理"></a>三、Spring事务管理</h3><p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121220011623.png" alt="image-20200121220011623"></p>
<h4 id="1-事务读取类型"><a href="#1-事务读取类型" class="headerlink" title="1.事务读取类型"></a>1.事务读取类型</h4><ul>
<li><p>脏读</p>
<p>事务没提交，提前读取</p>
</li>
</ul>
<ul>
<li><p>不可重复读</p>
<p>在一个事务内，多次读取同一个数据不相同</p>
</li>
<li><p>幻读</p>
<p>事务不是独立执行时出现的一种非预期的现象，如一个事务将表中所有人的性别改为男，但是另一个事务添加一个女性记录，事务执行完后发现表中并不是所有人都是男性</p>
</li>
</ul>
<h4 id="2-事务隔离级别"><a href="#2-事务隔离级别" class="headerlink" title="2.事务隔离级别"></a>2.事务隔离级别</h4><p>概念:</p>
<p>隔离级别定义了一个事务可能受其他并发事务的影响程度</p>
<p>分类:</p>
<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121221112524.png" alt="image-20200121221112524"></p>
<h4 id="3-事务传播行为"><a href="#3-事务传播行为" class="headerlink" title="3.事务传播行为"></a>3.事务传播行为</h4><p>概念：</p>
<p>当一个事务方法被另一个事务方法调用时，必须指定事务应该如何传播</p>
<p>分类:</p>
<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121221606960.png" alt="image-20200121221606960"></p>
<h4 id="4-事务是否只读"><a href="#4-事务是否只读" class="headerlink" title="4.事务是否只读"></a>4.事务是否只读</h4><p>因数据库而异</p>
<p>oracle不起作用</p>
<p>mysql的开启只读后，只能查，不能增删改</p>
<h4 id="5-事务超时"><a href="#5-事务超时" class="headerlink" title="5.事务超时"></a>5.事务超时</h4><p>事务必须在指定时间内完成，若没有完成则自动回滚</p>
<h4 id="6-事务的回滚"><a href="#6-事务的回滚" class="headerlink" title="6.事务的回滚"></a>6.事务的回滚</h4><p>事务会因为运行时异常而回滚，而这些事务都记录在事务的状态里，通过事务的状态决定是否回滚或提交</p>
<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121223321270.png" alt="image-20200121223321270"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/Spring%E4%BA%8B%E5%8A%A1/" data-id="ckdkdagv1000kvouthyq19cv6" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/Springmvc知识整理" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/Springmvc%E7%9F%A5%E8%AF%86%E6%95%B4%E7%90%86/" class="article-date">
  <time datetime="2020-08-07T15:08:02.062Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="Springmvc知识整理"><a href="#Springmvc知识整理" class="headerlink" title="Springmvc知识整理"></a>Springmvc知识整理</h2><h3 id="一、Springmvc是什么？"><a href="#一、Springmvc是什么？" class="headerlink" title="一、Springmvc是什么？"></a>一、Springmvc是什么？</h3><pre><code>- 目前实现mvc模式最好的框架
- spring的后续产品
- spring的子模块，不需要整合</code></pre>
<h3 id="二、-Springmvc的核心组件"><a href="#二、-Springmvc的核心组件" class="headerlink" title="二、 Springmvc的核心组件"></a>二、 Springmvc的核心组件</h3><ol>
<li><p>DisptcherServlet:前置控制器，对其他组件进行控制交互，降低组件间的耦合度</p>
</li>
<li><p>Handler:处理器，完成具体的业务逻辑，也就是我们编写的Controller中的方法，每一个方法是一个Handler</p>
</li>
<li><p>HandlerMapping：将请求映射到不同的Handler中交由Handler处理</p>
</li>
<li><p>HandlerInterceptor:处理器拦截器，可以拦截到Handler的请求并做一些处理，如权限验证</p>
</li>
<li><p>HandlerExecutionChain：处理器执行链,执行Handler时将其与拦截器封装成一个可执行的执行链对象进行操作</p>
</li>
<li><p>HandlerAdapter:处理器适配器，Handler中只有我们写的代码，但是Handler需要实现注解的功能，其就是有HandlerAdapter进行适配执行的，执行过程如下:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">graph TB</span><br><span class="line">查找handler上的表单或参数等注解 --&gt; 根据注解完成操作 --&gt; 执行Handler --&gt; 根据返回结果相关的注解处理结果为视图或json等</span><br></pre></td></tr></table></figure>



</li>
</ol>
<ol start="7">
<li>ModelAndView: 装载模型数据和视图信息</li>
<li>ViewResovler: 将逻辑视图解析为物理视图，如/user/login.jsp会指向相应的login.jsp并返回给前端</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">graph TB</span><br><span class="line">发送请求至DispatchServlet --&gt; DispatcherServlet通过HandlerMapping将请求映射到一个具体的Handler --&gt; 生成Handler和HandlerInterceptor返回为HandlerExecutionChain --&gt; 通过HandlerAdapter执行Handler --&gt; 返回ModelAndView --&gt; 通过ViewResovler进行解析 --&gt; 返回填充了模型数据的view给前端</span><br></pre></td></tr></table></figure>

<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200119145836552.png" alt="image-20200119145836552"></p>
<h3 id="三、springmvc的配置-不重要"><a href="#三、springmvc的配置-不重要" class="headerlink" title="三、springmvc的配置(不重要)"></a>三、springmvc的配置(不重要)</h3><ol>
<li><p>创建Maven工程</p>
</li>
<li><p>配置springmvc依赖(可以通过<a target="_blank" rel="noopener" href="https://mvnrepository.com/artifact/org.springframework/spring-webmvc/5.1.5.RELEASE">此网站</a>搜索依赖)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- https:&#x2F;&#x2F;mvnrepository.com&#x2F;artifact&#x2F;org.springframework&#x2F;spring-webmvc --&gt;</span><br><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework&lt;&#x2F;groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-webmvc&lt;&#x2F;artifactId&gt;</span><br><span class="line">    &lt;version&gt;5.1.5.RELEASE&lt;&#x2F;version&gt;</span><br><span class="line">&lt;&#x2F;dependency&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>web.xml中配置servlet</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>dispatcherServlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></span><br><span class="line">   // 这里配置springmvc配置文件加载的位置</span><br><span class="line">   <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>classpath:springmvc.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line">   </span><br><span class="line"> <span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>dispatcherServlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>编写自定义的Handler</p>
</li>
<li><p>配置处理器映射器、ViewResovler（在springmvc.xml中）</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--配置处理器映射器--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;</span> &gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;mappings&quot;</span>&gt;</span></span><br><span class="line">          <span class="tag">&lt;<span class="name">props</span>&gt;</span></span><br><span class="line">              <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">&quot;myController&quot;</span>&gt;</span>myController<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">          <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!--配置处理器--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;com.originit.mvc.controller.MyController&quot;</span> <span class="attr">id</span>=<span class="string">&quot;myController&quot;</span> /&gt;</span></span><br><span class="line">   </span><br><span class="line">  <span class="comment">&lt;!--配置视图处理器--&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;</span> &gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;prefix&quot;</span> <span class="attr">value</span>=<span class="string">&quot;/&quot;</span> /&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;suffix&quot;</span> <span class="attr">value</span>=<span class="string">&quot;.jsp&quot;</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>运行</p>
</li>
</ol>
<p>遇到了问题：</p>
<ul>
<li><p>l表达式不转换。。。</p>
<p>解决办法:jsp的page标签上添加一个属性isIgnoreEL=false,如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;%@ page contentType&#x3D;&quot;text&#x2F;html;charset&#x3D;UTF-8&quot; language&#x3D;&quot;java&quot; isELIgnored&#x3D;&quot;false&quot; %&gt;</span><br></pre></td></tr></table></figure>



</li>
</ul>
<p>以上是通过xml配置进行，如果要通过注解配置的话只需要开启包扫描扫描controller(也称为Handler)即可,同时要对Controller添加注解</p>
<p>配置静态资源访问:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;servlet-mapping&gt;</span><br><span class="line">  &lt;servlet-name&gt;default&lt;&#x2F;servlet-name&gt;</span><br><span class="line">  &lt;url-pattern&gt;*.css&lt;&#x2F;url-pattern&gt;</span><br><span class="line">&lt;&#x2F;servlet-mapping&gt;</span><br></pre></td></tr></table></figure>






      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/Springmvc%E7%9F%A5%E8%AF%86%E6%95%B4%E7%90%86/" data-id="ckdkdagv0000jvoutgrfvfrlk" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/Shiro框架的学习" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/Shiro%E6%A1%86%E6%9E%B6%E7%9A%84%E5%AD%A6%E4%B9%A0/" class="article-date">
  <time datetime="2020-08-07T15:08:02.058Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="Shiro框架的学习"><a href="#Shiro框架的学习" class="headerlink" title="Shiro框架的学习"></a>Shiro框架的学习</h2><h3 id="1-简介"><a href="#1-简介" class="headerlink" title="1. 简介"></a>1. 简介</h3><p>Apach的一个开源安全框架，支持认证、授权、企业级session管理、加密等功能</p>
<h3 id="2-Spring-Security-和-Shiro对比"><a href="#2-Spring-Security-和-Shiro对比" class="headerlink" title="2. Spring Security 和 Shiro对比"></a>2. Spring Security 和 Shiro对比</h3><p>Shiro:简单灵活</p>
<p>Spring Security:笨重，不可脱离spring</p>
<h3 id="3-Shiro的整体架构"><a href="#3-Shiro的整体架构" class="headerlink" title="3. Shiro的整体架构"></a>3. Shiro的整体架构</h3><p><img src="C:\Users\xxc\AppData\Roaming\Typora\typora-user-images\image-20200130111623415.png" alt="image-20200130111623415"></p>
<h3 id="4-Shiro认证"><a href="#4-Shiro认证" class="headerlink" title="4. Shiro认证"></a>4. Shiro认证</h3><p><img src="C:\Users\xxc\AppData\Roaming\Typora\typora-user-images\image-20200130111934396.png" alt="image-20200130111934396"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F; 1. 构造securityManager</span><br><span class="line">  DefaultSecurityManager securityManager &#x3D; new DefaultSecurityManager();</span><br><span class="line">  &#x2F;&#x2F; 2. 配置Realm源</span><br><span class="line">  securityManager.setRealm(realm);</span><br><span class="line">  SecurityUtils.setSecurityManager(securityManager);</span><br><span class="line">  &#x2F;&#x2F; 获取主体</span><br><span class="line">  final Subject subject &#x3D; SecurityUtils.getSubject();</span><br><span class="line">  UsernamePasswordToken token &#x3D; new UsernamePasswordToken(&quot;xxc&quot;,&quot;123456&quot;);</span><br><span class="line">  &#x2F;&#x2F; 认证</span><br><span class="line">  subject.login(token);</span><br><span class="line">  Assert.assertTrue(subject.isAuthenticated());</span><br><span class="line">  &#x2F;&#x2F; 登出</span><br><span class="line">  subject.logout();</span><br><span class="line">  Assert.assertFalse(subject.isAuthenticated());</span><br></pre></td></tr></table></figure>

<p>内部通过authenticator进行认证</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException &#123;</span><br><span class="line">        return this.authenticator.authenticate(token);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>



<h3 id="5-Shiro授权"><a href="#5-Shiro授权" class="headerlink" title="5. Shiro授权"></a>5. Shiro授权</h3><p><img src="C:\Users\xxc\AppData\Roaming\Typora\typora-user-images\image-20200130113058271.png" alt="image-20200130113058271"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F; 授权，若无权限抛出异常</span><br><span class="line"> subject.checkRole(&quot;admin&quot;);</span><br></pre></td></tr></table></figure>

<p>内部通过authorizer进行授权 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">public void checkRole(PrincipalCollection principals, String role) throws AuthorizationException &#123;</span><br><span class="line">       this.authorizer.checkRole(principals, role);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="6-自定义Realm"><a href="#6-自定义Realm" class="headerlink" title="6.自定义Realm"></a>6.自定义Realm</h3><p>做自定义登录授权规则</p>
<ol>
<li>认证</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException &#123;</span><br><span class="line">        &#x2F;&#x2F; 将token转换为相应类型，一般登录时传什么这里就获取什么，以获取详细信息</span><br><span class="line">        UsernamePasswordToken token &#x3D; (UsernamePasswordToken) authenticationToken;</span><br><span class="line">        &#x2F;&#x2F; 通过数据库认证</span><br><span class="line">        final String username &#x3D; token.getUsername();</span><br><span class="line">        String password &#x3D; getPasswordByUserName(username);</span><br><span class="line">        if(password &#x3D;&#x3D; null) &#123;</span><br><span class="line">            &#x2F;&#x2F; 认证失败返回null</span><br><span class="line">            return null;</span><br><span class="line">        &#125;</span><br><span class="line">        &#x2F;&#x2F; 认证成功返回认证信息</span><br><span class="line">        return new SimpleAuthenticationInfo(username,password,&quot;customRealm&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>授权</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@Override</span><br><span class="line">protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) &#123;</span><br><span class="line">    String username &#x3D; (String) principalCollection.getPrimaryPrincipal();</span><br><span class="line">    Set&lt;String&gt; roles &#x3D; getRolesByUsername(username);</span><br><span class="line">    return new SimpleAuthorizationInfo(roles);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="3">
<li><p>加密</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;给realm设置加密匹配器</span><br><span class="line">matcher.setHashAlgorithmName(&quot;MD5&quot;);</span><br><span class="line">       matcher.setHashIterations(1);</span><br><span class="line">       realm.setCredentialsMatcher(matcher);</span><br><span class="line">       </span><br><span class="line">&#x2F;&#x2F; realm中返回的info设置盐值</span><br><span class="line">    final SimpleAuthenticationInfo info &#x3D; new SimpleAuthenticationInfo(username,</span><br><span class="line">               password,</span><br><span class="line">               ByteSource.Util.bytes(&quot;mark&quot;), &#x2F;&#x2F; 盐</span><br><span class="line">               &quot;customRealm&quot;);</span><br></pre></td></tr></table></figure>



</li>
</ol>
<p>认证过程如下:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">graph TB</span><br><span class="line">主体提交用户token信息 --&gt; realm查找用户信息,并返回用户名密码盐值 --&gt; 认证器获取到用户信息进行加密比对 --密码比对成功--&gt; 认证成功</span><br></pre></td></tr></table></figure>

<h3 id="7-spring整合Shiro"><a href="#7-spring整合Shiro" class="headerlink" title="7.spring整合Shiro"></a>7.spring整合Shiro</h3><p>依赖 <strong>pom.xml</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.2.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-webmvc<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.2.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.shiro<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>shiro-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.4.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.shiro<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>shiro-spring<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.4.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>



<p><strong>web.xml</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">web-app</span> <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns</span>=<span class="string">&quot;http://java.sun.com/xml/ns/javaee&quot;</span> <span class="attr">xmlns:web</span>=<span class="string">&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">id</span>=<span class="string">&quot;WebApp_ID&quot;</span> <span class="attr">version</span>=<span class="string">&quot;2.5&quot;</span>&gt;</span></span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- ShiroFilter start --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">filter</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">filter-name</span>&gt;</span>shiroFilter<span class="tag">&lt;/<span class="name">filter-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">filter-class</span>&gt;</span>org.springframework.web.filter.DelegatingFilterProxy<span class="tag">&lt;/<span class="name">filter-class</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>targetFilterLifecycle<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>true<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">filter</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">filter-mapping</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">filter-name</span>&gt;</span>shiroFilter<span class="tag">&lt;/<span class="name">filter-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/*<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dispatcher</span>&gt;</span>REQUEST<span class="tag">&lt;/<span class="name">dispatcher</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">dispatcher</span>&gt;</span>FORWARD<span class="tag">&lt;/<span class="name">dispatcher</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">filter-mapping</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- ShiroFilter end --&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>dispatch<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>classpath:springmvc.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>dispatch<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/*<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">web-app</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>springmvc.xml</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:aop</span>=<span class="string">&quot;http://www.springframework.org/schema/aop&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:mvc</span>=<span class="string">&quot;http://www.springframework.org/schema/mvc&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/aop</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/aop/spring-aop.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/mvc</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/mvc/spring-mvc.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    &quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--扫描包--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.imooc&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--开启注解--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">mvc:annotation-driven</span> /&gt;</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">&lt;!--暴露静态资源--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">mvc:resources</span> <span class="attr">mapping</span>=<span class="string">&quot;/*&quot;</span> <span class="attr">location</span>=<span class="string">&quot;/&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--引入shiro的配置--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">import</span> <span class="attr">resource</span>=<span class="string">&quot;springshiro.xml&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>



<p><strong>springshiro.xml</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:aop</span>=<span class="string">&quot;http://www.springframework.org/schema/aop&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:mvc</span>=<span class="string">&quot;http://www.springframework.org/schema/mvc&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/aop</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/aop/spring-aop.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/context/spring-context.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/mvc</span></span></span><br><span class="line"><span class="tag"><span class="string">    http://www.springframework.org/schema/mvc/spring-mvc.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">    &quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--配置过滤器--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;shiroFilter&quot;</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.spring.web.ShiroFilterFactoryBean&quot;</span> &gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;securityManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;securityManager&quot;</span> /&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--登录页面--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;loginUrl&quot;</span> <span class="attr">value</span>=<span class="string">&quot;login.html&quot;</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;unauthorizedUrl&quot;</span> <span class="attr">value</span>=<span class="string">&quot;403.html&quot;</span> /&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--过滤规则--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;filterChainDefinitions&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span></span><br><span class="line">                /login.html = anon</span><br><span class="line">                /user/login = anon</span><br><span class="line">                /* = authc</span><br><span class="line">            <span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--web场景使用web的securityManager--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.web.mgt.DefaultWebSecurityManager&quot;</span> <span class="attr">id</span>=<span class="string">&quot;securityManager&quot;</span> &gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;realm&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;realm&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--自定义realm--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;realm&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.imooc.CustomRealm&quot;</span> &gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;credentialsMatcher&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;matcher&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--配置加密--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.authc.credential.HashedCredentialsMatcher&quot;</span> <span class="attr">id</span>=<span class="string">&quot;matcher&quot;</span> &gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;hashAlgorithmName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;md5&quot;</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;hashIterations&quot;</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--配置使用注解声明权限--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">aop:config</span> <span class="attr">proxy-target-class</span>=<span class="string">&quot;true&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.spring.LifecycleBeanPostProcessor&quot;</span> /&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor&quot;</span> &gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;securityManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;securityManager&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>CustomRealm</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.imooc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authc.*;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authz.AuthorizationInfo;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authz.SimpleAuthorizationInfo;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.realm.AuthorizingRealm;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.subject.PrincipalCollection;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.util.ByteSource;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.HashSet;</span><br><span class="line"><span class="keyword">import</span> java.util.Set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomRealm</span> <span class="keyword">extends</span> <span class="title">AuthorizingRealm</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> HashMap&lt;String,String&gt; userMap = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    &#123;</span><br><span class="line">        userMap.put(<span class="string">&quot;xxc&quot;</span>,<span class="string">&quot;73bea81c6c06bacab41a995495239545&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> AuthorizationInfo <span class="title">doGetAuthorizationInfo</span><span class="params">(PrincipalCollection principalCollection)</span> </span>&#123;</span><br><span class="line">        String username = (String) principalCollection.getPrimaryPrincipal();</span><br><span class="line">        Set&lt;String&gt; roles = getRolesByUsername(username);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> SimpleAuthorizationInfo(roles);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> Set&lt;String&gt; <span class="title">getRolesByUsername</span><span class="params">(String username)</span> </span>&#123;</span><br><span class="line">        Set&lt;String&gt; roles = <span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">        roles.add(<span class="string">&quot;admin&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> roles;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> AuthenticationInfo <span class="title">doGetAuthenticationInfo</span><span class="params">(AuthenticationToken authenticationToken)</span> <span class="keyword">throws</span> AuthenticationException </span>&#123;</span><br><span class="line">        <span class="comment">// 将token转换为相应类型，一般登录时传什么这里就获取什么，以获取详细信息</span></span><br><span class="line">        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;</span><br><span class="line">        <span class="comment">// 通过数据库查找是否有该用户</span></span><br><span class="line">        <span class="keyword">final</span> String username = token.getUsername();</span><br><span class="line">        String password = getPasswordByUserName(username);</span><br><span class="line">        <span class="keyword">if</span>(password == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">// 没有返回null</span></span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">final</span> SimpleAuthenticationInfo info = <span class="keyword">new</span> SimpleAuthenticationInfo(username,</span><br><span class="line">                password,</span><br><span class="line">                ByteSource.Util.bytes(<span class="string">&quot;mark&quot;</span>),</span><br><span class="line">                <span class="string">&quot;customRealm&quot;</span>);</span><br><span class="line">        <span class="comment">// 有的话返回用户信息</span></span><br><span class="line">        <span class="keyword">return</span> info;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> String <span class="title">getPasswordByUserName</span><span class="params">(String username)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> userMap.get(username);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>UserController</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.imooc.controller;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.SecurityUtils;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authc.AuthenticationException;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authc.UsernamePasswordToken;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.authz.annotation.RequiresRoles;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.subject.Subject;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Controller;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.*;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@RequestMapping(&quot;/user&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 登录</span></span><br><span class="line">    <span class="meta">@PostMapping(value = &quot;/login&quot;,produces = &quot;application/json;charset=utf-8&quot;)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">login</span><span class="params">(<span class="meta">@RequestParam</span> String username,<span class="meta">@RequestParam</span> String password)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 获取主体</span></span><br><span class="line">        <span class="keyword">final</span> Subject subject = SecurityUtils.getSubject();</span><br><span class="line">        UsernamePasswordToken token = <span class="keyword">new</span> UsernamePasswordToken(username,password);</span><br><span class="line">        <span class="comment">// 认证</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            subject.login(token);</span><br><span class="line">        &#125;<span class="keyword">catch</span> (AuthenticationException e)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> e.getMessage();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;登录成功&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试权限验证    </span></span><br><span class="line">    <span class="meta">@GetMapping(value = &quot;/testRole1&quot;,produces = &quot;application/json;charset=utf-8&quot;)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="meta">@RequiresRoles(&quot;admin&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">testRole1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;test Role1&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping(value = &quot;/testRole2&quot;,produces = &quot;application/json;charset=utf-8&quot;)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="meta">@RequiresRoles(&quot;admin1&quot;)</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">testRole2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;test Role2&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p>shiro内置过滤器</p>
<ul>
<li><p>anon,authBasic,authc,user,logout</p>
<p>无需认证,不知，需要认证才能访问，需要当前存在用户，退出</p>
</li>
<li><p>perms,roles,ssl,port</p>
<p>要求中括号中的权限，要求中括号中的角色，要求安全协议，要求中括号中的端口</p>
</li>
</ul>
</li>
<li><p>自定义filter</p>
<p>继承AuthorizationFilter或者AuthenticatingFilter,具体根据是认证还是授权继承，配置中中括号的值为object，可以强转为String[]，返回true为授权通过</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.imooc.filter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.subject.Subject;</span><br><span class="line"><span class="keyword">import</span> org.apache.shiro.web.filter.authz.AuthorizationFilter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RolesOrFilter</span> <span class="keyword">extends</span> <span class="title">AuthorizationFilter</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> servletRequest</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> servletResponse</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> o 中括号中的数据</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> Exception</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">boolean</span> <span class="title">isAccessAllowed</span><span class="params">(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse, Object o)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        Subject subject = getSubject(servletRequest,servletResponse);</span><br><span class="line">        String[] roles = (String[]) o;</span><br><span class="line">        <span class="keyword">for</span> (String role : roles) &#123;</span><br><span class="line">            <span class="keyword">if</span> (subject.hasRole(role)) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>配置过滤器</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--配置过滤器--&gt;</span><br><span class="line"> &lt;bean id&#x3D;&quot;shiroFilter&quot; class&#x3D;&quot;org.apache.shiro.spring.web.ShiroFilterFactoryBean&quot; &gt;</span><br><span class="line">     &lt;property name&#x3D;&quot;securityManager&quot; ref&#x3D;&quot;securityManager&quot; &#x2F;&gt;</span><br><span class="line">     &lt;!--登录页面--&gt;</span><br><span class="line">     &lt;property name&#x3D;&quot;loginUrl&quot; value&#x3D;&quot;login.html&quot; &#x2F;&gt;</span><br><span class="line">     &lt;property name&#x3D;&quot;unauthorizedUrl&quot; value&#x3D;&quot;403.html&quot; &#x2F;&gt;</span><br><span class="line">     &lt;!-- 这里配置了filter以及他的名称 --&gt;</span><br><span class="line">     &lt;property name&#x3D;&quot;filters&quot;&gt;</span><br><span class="line">         &lt;map&gt;</span><br><span class="line">             &lt;entry key&#x3D;&quot;roleOr&quot; value-ref&#x3D;&quot;rolesOrFilter&quot; &#x2F;&gt;</span><br><span class="line">         &lt;&#x2F;map&gt;</span><br><span class="line">     &lt;&#x2F;property&gt;</span><br><span class="line">     &lt;!--过滤规则,使用roleOr--&gt;</span><br><span class="line">     &lt;property name&#x3D;&quot;filterChainDefinitions&quot;&gt;</span><br><span class="line">         &lt;value&gt;</span><br><span class="line">             &#x2F;user&#x2F;testRole3 &#x3D; roleOr[&quot;admin&quot;,&quot;good&quot;]</span><br><span class="line">             &#x2F;login.html &#x3D; anon</span><br><span class="line">             &#x2F;user&#x2F;login &#x3D; anon</span><br><span class="line">             &#x2F;* &#x3D; authc</span><br><span class="line">         &lt;&#x2F;value&gt;</span><br><span class="line">     &lt;&#x2F;property&gt;</span><br><span class="line"> &lt;&#x2F;bean&gt;</span><br><span class="line">&lt;!-- 配置filerBean --&gt;</span><br><span class="line"> &lt;bean class&#x3D;&quot;com.imooc.filter.RolesOrFilter&quot; id&#x3D;&quot;rolesOrFilter&quot; &#x2F;&gt;</span><br></pre></td></tr></table></figure>



</li>
</ul>
<h3 id="8-Shiro会话管理"><a href="#8-Shiro会话管理" class="headerlink" title="8. Shiro会话管理"></a>8. Shiro会话管理</h3><p>​    用来自定义会话管理，方便对其进行优化，如使用redis缓存</p>
<ol>
<li>编写自定义的SessionDAO继承AbstractSessionDAO,使用redis保存session</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisSessionDAO</span> <span class="keyword">extends</span> <span class="title">AbstractSessionDAO</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String SHIRO_KEY_PREFIX = <span class="string">&quot;jedis:shiro/&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> JedisUtil jedisUtil;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">byte</span>[] getKey(String sessionId)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> (SHIRO_KEY_PREFIX + sessionId).getBytes();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">saveSession</span> <span class="params">(Session session)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">byte</span>[] key = getKey(session.getId().toString());</span><br><span class="line">        jedisUtil.set(key, SerializationUtils.serialize(session));</span><br><span class="line">        jedisUtil.expire(key,<span class="number">600</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Serializable <span class="title">doCreate</span><span class="params">(Session session)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">final</span> Serializable sessionId = getSessionIdGenerator().generateId(session);</span><br><span class="line">        assignSessionId(session,sessionId);</span><br><span class="line">        saveSession(session);</span><br><span class="line">        <span class="keyword">return</span> sessionId;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Session <span class="title">doReadSession</span><span class="params">(Serializable serializable)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">byte</span>[] key = getKey(serializable.toString());</span><br><span class="line">        System.out.println(<span class="string">&quot;readSession&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> (Session) SerializationUtils.deserialize(jedisUtil.get(key));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">update</span><span class="params">(Session session)</span> <span class="keyword">throws</span> UnknownSessionException </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(session != <span class="keyword">null</span> &amp;&amp; session.getId() != <span class="keyword">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            saveSession(session);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">delete</span><span class="params">(Session session)</span> </span>&#123;</span><br><span class="line">        jedisUtil.del(getKey(session.getId().toString()));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Collection&lt;Session&gt; <span class="title">getActiveSessions</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Set&lt;String&gt; keys = jedisUtil.keys(SHIRO_KEY_PREFIX);</span><br><span class="line">        Set&lt;Session&gt; sessions = <span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (!keys.isEmpty()) &#123;</span><br><span class="line">            <span class="keyword">for</span> (String key : keys) &#123;</span><br><span class="line">                sessions.add((Session) SerializationUtils.deserialize(jedisUtil.get(key.getBytes())));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sessions;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<ol start="2">
<li><p>编写自定义SessionManager</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">package com.imooc.session;</span><br><span class="line"></span><br><span class="line">import org.apache.shiro.session.Session;</span><br><span class="line">import org.apache.shiro.session.UnknownSessionException;</span><br><span class="line">import org.apache.shiro.session.mgt.SessionKey;</span><br><span class="line">import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;</span><br><span class="line">import org.apache.shiro.web.session.mgt.WebSessionKey;</span><br><span class="line"></span><br><span class="line">import javax.servlet.ServletRequest;</span><br><span class="line">import java.io.Serializable;</span><br><span class="line"></span><br><span class="line">public class CustomSessionManager extends DefaultWebSessionManager &#123;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException &#123;</span><br><span class="line">        WebSessionKey webSessionKey &#x3D; (WebSessionKey) sessionKey;</span><br><span class="line">        final ServletRequest servletRequest &#x3D; webSessionKey.getServletRequest();</span><br><span class="line">        final Serializable sessionId &#x3D; webSessionKey.getSessionId();</span><br><span class="line">        if(sessionId !&#x3D; null &amp;&amp; servletRequest !&#x3D; null)</span><br><span class="line">        &#123;</span><br><span class="line">            Session session &#x3D;  (Session) servletRequest.getAttribute(sessionId.toString());</span><br><span class="line">            if (session !&#x3D; null) &#123;</span><br><span class="line">                return session;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        final Session session &#x3D; super.retrieveSession(sessionKey);</span><br><span class="line">        if(servletRequest !&#x3D; null)</span><br><span class="line">        &#123;</span><br><span class="line">            servletRequest.setAttribute(session.getId().toString(),session);</span><br><span class="line">        &#125;</span><br><span class="line">        return session;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



</li>
</ol>
<ol start="3">
<li><p>配置sessionDAO和SessionManager</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--web场景使用web的securityManager--&gt;</span><br><span class="line">&lt;bean class&#x3D;&quot;org.apache.shiro.web.mgt.DefaultWebSecurityManager&quot; id&#x3D;&quot;securityManager&quot; &gt;</span><br><span class="line">    &lt;property name&#x3D;&quot;realm&quot; ref&#x3D;&quot;realm&quot; &#x2F;&gt;</span><br><span class="line">    &lt;property name&#x3D;&quot;sessionManager&quot; ref&#x3D;&quot;sessionManager&quot; &#x2F;&gt;</span><br><span class="line">&lt;&#x2F;bean&gt;</span><br><span class="line">   </span><br><span class="line">&lt;bean class&#x3D;&quot;com.imooc.session.CustomSessionManager&quot; id&#x3D;&quot;sessionManager&quot; &gt;</span><br><span class="line">    &lt;property name&#x3D;&quot;sessionDAO&quot; ref&#x3D;&quot;redisSessionDAO&quot; &#x2F;&gt;</span><br><span class="line">&lt;&#x2F;bean&gt;</span><br><span class="line">   </span><br><span class="line">&lt;bean id&#x3D;&quot;redisSessionDAO&quot; class&#x3D;&quot;com.imooc.session.RedisSessionDAO&quot; &#x2F;&gt;</span><br><span class="line">   </span><br></pre></td></tr></table></figure>



</li>
</ol>
<h3 id="9-Shiro缓存管理"><a href="#9-Shiro缓存管理" class="headerlink" title="9.Shiro缓存管理"></a>9.Shiro缓存管理</h3><p>CacheManager、Cache</p>
<p>用于缓存权限信息，减少对数据库的操作，缓存中没有数据时才会去查找数据库</p>
<ol>
<li><p>自定义CacheManager</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisCacheManager</span> <span class="keyword">implements</span> <span class="title">CacheManager</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> RedisCache redisCache;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> &lt;K, V&gt; <span class="function">Cache&lt;K, V&gt; <span class="title">getCache</span><span class="params">(String s)</span> <span class="keyword">throws</span> CacheException </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> redisCache;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>自定义Cache</p>
<p>需要加入springBean容器，如果自己new出来会出现问题，暂时不知道为什么</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">@Component</span><br><span class="line">public class RedisCache&lt;K,V&gt; implements Cache&lt;K,V&gt; &#123;</span><br><span class="line"></span><br><span class="line">    public static final String CACHE_PREFIX &#x3D; &quot;cache:shiro&#x2F;&quot;;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private JedisUtil jedisUtil;</span><br><span class="line"></span><br><span class="line">    private byte[] getKey(K key)&#123;</span><br><span class="line">        return (CACHE_PREFIX + key.toString()).getBytes();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public V get(K k) throws CacheException &#123;</span><br><span class="line">        System.out.println(&quot;redis&quot;);</span><br><span class="line">        return (V) SerializationUtils.deserialize(jedisUtil.get(getKey(k)));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public V put(K k, V v) throws CacheException &#123;</span><br><span class="line">        SerializationUtils.deserialize(jedisUtil.set(getKey(k),SerializationUtils.serialize(v)));</span><br><span class="line">        return v;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public V remove(K k) throws CacheException &#123;</span><br><span class="line">        final V v &#x3D; get(k);</span><br><span class="line">        jedisUtil.del(getKey(k));</span><br><span class="line">        return v;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public void clear() throws CacheException &#123;</span><br><span class="line">        final Set&lt;String&gt; keys &#x3D; jedisUtil.keys(CACHE_PREFIX);</span><br><span class="line">        for (String key : keys) &#123;</span><br><span class="line">            jedisUtil.del(key.getBytes());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public int size() &#123;</span><br><span class="line">        return 0;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public Set&lt;K&gt; keys() &#123;</span><br><span class="line">        return null;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public Collection&lt;V&gt; values() &#123;</span><br><span class="line">        return null;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</li>
<li><p>配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--web场景使用web的securityManager--&gt;</span></span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.web.mgt.DefaultWebSecurityManager&quot;</span> <span class="attr">id</span>=<span class="string">&quot;securityManager&quot;</span> &gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;realm&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;realm&quot;</span> /&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;sessionManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;sessionManager&quot;</span> /&gt;</span></span><br><span class="line">       <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cacheManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;cacheManager&quot;</span> /&gt;</span></span><br><span class="line">   <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">   </span><br><span class="line">   <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;com.imooc.session.RedisCacheManager&quot;</span> <span class="attr">id</span>=<span class="string">&quot;cacheManager&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure>

</li>
</ol>
<h3 id="10-rememberMe"><a href="#10-rememberMe" class="headerlink" title="10.rememberMe"></a>10.rememberMe</h3><p>配置CookieRemeberMeManager即可，原理是在浏览器放置一个cookie值，服务器端进行保存，下次进入该网站会根据带过来的cookie进行自动登录</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--web场景使用web的securityManager--&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.web.mgt.DefaultWebSecurityManager&quot;</span> <span class="attr">id</span>=<span class="string">&quot;securityManager&quot;</span> &gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;realm&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;realm&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;sessionManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;sessionManager&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cacheManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;cacheManager&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;rememberMeManager&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;cookieRememberMeManager&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"> <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.web.mgt.CookieRememberMeManager&quot;</span> <span class="attr">id</span>=<span class="string">&quot;cookieRememberMeManager&quot;</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cookie&quot;</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">&quot;org.apache.shiro.web.servlet.SimpleCookie&quot;</span> &gt;</span></span><br><span class="line">             <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;name&quot;</span> <span class="attr">value</span>=<span class="string">&quot;rememberMe&quot;</span> /&gt;</span></span><br><span class="line">             <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;maxAge&quot;</span> <span class="attr">value</span>=<span class="string">&quot;18000000&quot;</span> /&gt;</span></span><br><span class="line">         <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>



<p>注意:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">final Subject subject &#x3D; SecurityUtils.getSubject();</span><br><span class="line">     UsernamePasswordToken token &#x3D; new UsernamePasswordToken(username,password);</span><br><span class="line">     &#x2F;&#x2F; 这里要跟根据情况设置是否rememberMe，如果true，则可以记住登录</span><br><span class="line">     token.setRememberMe(true);</span><br><span class="line">     &#x2F;&#x2F; 认证</span><br><span class="line">     try &#123;</span><br><span class="line">         subject.login(token);</span><br><span class="line">     &#125;catch (AuthenticationException e)</span><br><span class="line">     &#123;</span><br><span class="line">         return e.getMessage();</span><br><span class="line">     &#125;</span><br></pre></td></tr></table></figure>


      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/Shiro%E6%A1%86%E6%9E%B6%E7%9A%84%E5%AD%A6%E4%B9%A0/" data-id="ckdkdagw90013vout0sd6dyne" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/MyBatis详解" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/MyBatis%E8%AF%A6%E8%A7%A3/" class="article-date">
  <time datetime="2020-08-07T15:08:02.055Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="MyBatis详解"><a href="#MyBatis详解" class="headerlink" title="MyBatis详解"></a>MyBatis详解</h3><h3 id="一、四大组件"><a href="#一、四大组件" class="headerlink" title="一、四大组件"></a>一、四大组件</h3><h4 id="1、ParameterHandler"><a href="#1、ParameterHandler" class="headerlink" title="1、ParameterHandler"></a>1、ParameterHandler</h4><p>​     处理SQL的参数</p>
<h4 id="2、-ResultSetHandler"><a href="#2、-ResultSetHandler" class="headerlink" title="2、 ResultSetHandler"></a>2、 ResultSetHandler</h4><p>​    处理SQL返回的结果集</p>
<h4 id="3、StatementHandler"><a href="#3、StatementHandler" class="headerlink" title="3、StatementHandler"></a>3、StatementHandler</h4><p>​    数据库处理对象，负责执行SQL语句</p>
<h4 id="4、-Executor"><a href="#4、-Executor" class="headerlink" title="4、 Executor"></a>4、 Executor</h4><p>​    Mybatis执行器，用于执行增删改查操作</p>
<h4 id="5、原理"><a href="#5、原理" class="headerlink" title="5、原理"></a>5、原理</h4><p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121204201487.png" alt="image-20200121204201487"></p>
<ul>
<li>使用责任链模式</li>
<li>动态代理增强四大组件</li>
</ul>
<p>mybatis的四大组件都是通过上面这样的方式进行代理生成的，拦截器会被加入到interceptorChain中，故我们可以通过拦截器控制底层逻辑</p>
<p><img src="C:\Users\xxc、\AppData\Roaming\Typora\typora-user-images\image-20200121200843585.png" alt="image-20200121200843585"></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/MyBatis%E8%AF%A6%E8%A7%A3/" data-id="ckdkdaguw000hvout9taj93e5" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-后端/java数据库标准" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="./2020/08/07/%E5%90%8E%E7%AB%AF/java%E6%95%B0%E6%8D%AE%E5%BA%93%E6%A0%87%E5%87%86/" class="article-date">
  <time datetime="2020-08-07T15:08:02.051Z" itemprop="datePublished">2020-08-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="java数据库标准"><a href="#java数据库标准" class="headerlink" title="java数据库标准"></a>java数据库标准</h2><h3 id="1-DriverManager"><a href="#1-DriverManager" class="headerlink" title="1. DriverManager"></a>1. DriverManager</h3><p>由于不同的数据库底层各不相同，java官方无法提供所有的数据库连接的实现，故定义一个DriverManager接口以获取数据库连接，实现由各厂商提供，而开发人员只需要面相java.sql.DriverManager接口编程，无需关心具体连接的是哪一个数据库</p>
<h3 id="2-DataSource"><a href="#2-DataSource" class="headerlink" title="2.DataSource"></a>2.DataSource</h3><p>数据源接口，用于获取数据库连接的统一接口。DriverManager也是获取数据库连接的统一接口，他们之间的区别是，前者面相的是具体的数据库，去真正的连接数据库，获取到连接之后可能会通过数据库连接池等对连接进行优化处理，而后者正是在此情况下进行的统一封装，具体如何优化交由个数据库连接池厂商，而用户只需提供数据库连接信息，我们便能从DataSource接口中获取优化后的连接</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2020/08/07/%E5%90%8E%E7%AB%AF/java%E6%95%B0%E6%8D%AE%E5%BA%93%E6%A0%87%E5%87%86/" data-id="ckdkdagv6000nvout06p77epp" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="./page/2/">&amp;laquo; Prev</a><a class="page-number" href="./">1</a><a class="page-number" href="./page/2/">2</a><span class="page-number current">3</span><a class="page-number" href="./page/4/">4</a><a class="extend next" rel="next" href="./page/4/">Next &amp;raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="./archives/2020/08/">August 2020</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="./2020/08/07/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E9%93%BE%E8%A1%A8/">(no title)</a>
          </li>
        
          <li>
            <a href="./2020/08/07/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97/">(no title)</a>
          </li>
        
          <li>
            <a href="./2020/08/07/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E6%95%B0%E7%BB%84/">(no title)</a>
          </li>
        
          <li>
            <a href="./2020/08/07/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/">(no title)</a>
          </li>
        
          <li>
            <a href="./2020/08/07/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/SpringBoot%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2020 xiaxuchen<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="./" class="mobile-nav-link">Home</a>
  
    <a href="./archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="./fancybox/jquery.fancybox.css">

  
<script src="./fancybox/jquery.fancybox.pack.js"></script>




<script src="./js/script.js"></script>




  </div>
</body>
</html>